import { useRef, useState } from 'react';

function getUsername(): Promise<string> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // const name = '@name' + Math.random();
      // resolve(name);
      console.log('--getUsername--触发--');
      resolve('@name' + Math.random());
    }, 1000);
  });
}

function useCustomRequest(fn: Function) {
  const [data, setData] = useState<any>();
  const [loading, setLoading] = useState(false);

  return {
    loading,
    data,
    run: () => {
      setLoading(true);
      fn()
        .then((res: any) => {
          setData(res);
        })
        .finally(() => {
          setLoading(false);
        });
    },
  };
}

//-------------useRequest----------------
class Fetch {
  fn: Function;
  data: any;
  loading: boolean = false;
  constructor(fn: Function) {
    this.fn = fn;
  }
  run() {
    this.loading = true;
    this.fn()
      .then((res: any) => {
        this.data = res;
      })
      .finally(() => {
        this.loading = false;
      });
  }
}

function useRequest(fn: Function) {
  const fetchInstanceRef = useRef<Fetch>();
  if (!fetchInstanceRef.current) {
    fetchInstanceRef.current = new Fetch(fn);
  }
  return {
    loading: fetchInstanceRef.current.loading,
    data: fetchInstanceRef.current.data,
    run: fetchInstanceRef.current.run.bind(fetchInstanceRef.current),
  };
}

function PrincipleAnalysis() {
  const { loading, data, run } = useCustomRequest(getUsername);
  const { loading: loading2, data: data2, run: run2 } = useRequest(getUsername);

  return (
    <div>
      <h3>原理分析</h3>
      <div style={{ marginTop: '30px' }}>
        <p>useCustomRequest---=data:{data}</p>
        <p>useCustomRequest.loading/data 是用useState定义的，return loading/data 就能获取到最新值</p>
        <button disabled={loading} onClick={run}>
          {loading ? 'loading' : 'run'}
        </button>
      </div>
      <div style={{ marginTop: '30px' }}>
        <p>useRequest---=data:{data2}</p>
        <button disabled={loading2} onClick={run2}>
          {loading2 ? 'loading' : 'run'}
        </button>
      </div>
    </div>
  );
}

export default PrincipleAnalysis;